import Dom from '../utils/Dom';
import Utils from '../utils/index';

import Dimmer from './Dimmer';

class Modal {
    /**
     * 模态窗
     * @param {string} title  标题
     * @param {string} content 内容
     * @param {function} callback 点击确认回调函数
     * @param {object} options 其他参数
     *  - type: 类型，目前有 modal 和 confirm 两种
     *  - static: 是否关闭背景（dimmer）点击行为
     */
    constructor(title, content, callback = Utils.noop, options) {

        if (!content) {
            // Logger.error('Modal 类初始化失败，缺少 `content` 参数', null, false);
            return false;
        }

        this.userOptions = Utils.extend({
            type: 'modal',
            static: false,
            dimmer: true,
            buttons: null
        }, options);

        if (this.userOptions.dimmer) {
            this.dimmer = new Dimmer(() => {
                this.destroy();
            }, {
                    ignoreClick: !this.userOptions.static,
                    opacity: 0.2
                });
        }

        // header
        this.modal = Dom.append(document.body, 'div', 'modal');
        if (this.userOptions.className) {
            this.modal.className += ' ' + this.userOptions.className;
        }
        this.header = Dom.append(this.modal, 'div', 'modal-header');
        this.title = Dom.append(this.header, 'h5', null, title || '操作确认');
        this.closer = Dom.append(this.header, 'div', 'modal-closer', '<i class="fa fa-times">x</i>');

        // body
        this.modalBody = Dom.append(this.modal, 'div', 'modal-body');

        // footer
        this.modalFooter = Dom.append(this.modal, 'div', 'modal-footer');


        if (this.userOptions.buttons) {
            this.buttons = [];
            this.userOptions.buttons.forEach((btn, index) => {
                let button = Dom.append(this.modalFooter, 'button', 'btn', btn);
                button.dataIndex = index;
                this.buttons.push(button);
            });
        } else {
            if (this.userOptions.type === 'alert') {
                this.cancelBtn = Dom.append(this.modalFooter, 'button', 'btn', '关闭');
            } else {
                this.successBtn = Dom.append(this.modalFooter, 'button', ['btn', 'btn-success'], this.userOptions.type === 'modal' ? '确定' : '确认');
                this.cancelBtn = Dom.append(this.modalFooter, 'button', 'btn', '取消');
            }
        }

        // messager
        if (this.userOptions.type === 'modal') {
            this.messager = Dom.append(this.modalFooter, 'div', 'modal-messager');
        }

        // 事件
        Dom.addEvent(this.modalFooter, 'click', e => {
            if (e.target.className.indexOf('btn') !== -1) {
                if (this.userOptions.buttons) {
                    callback(e.target.dataIndex);
                    return false;
                }
                let isOk = e.target.className.indexOf('btn-success') !== -1;
                
                if (callback(isOk) || !isOk) {
                    this.destroy();
                }
            }
        });

        Dom.addEvent(this.closer, 'click', e => {
            callback(false);
            this.destroy();
        });


        // 拖动
        let dragging = false,
            padding = 10,
            marginLeft = Dom.getStyles(this.modal, 'margin-left'),
            pos = null,
            size = null,
            newX = null,
            newY = null;


        marginLeft = marginLeft ? -parseInt(marginLeft) : 0;

        Dom.addEvent(this.header, 'mousedown', e => {
            dragging = [e.clientX, e.clientY];
            return Dom.nodefault(e);
        });

        Dom.addEvent(document.body, 'mousemove', e => {
            if (dragging) {
                pos = Dom.pos(this.modal, true);
                size = Dom.size(this.modal);
                newX = pos.x + marginLeft + e.clientX - dragging[0];
                newY = pos.y + e.clientY - dragging[1];

                if (newX <= padding + marginLeft) {
                    newX = padding + marginLeft;
                } else if (newX + size.w + padding - marginLeft >= window.innerWidth) {
                    newX = window.innerWidth - size.w - padding + marginLeft;
                }

                if (newY <= padding) {
                    newY = padding;
                } else if (newY + size.h + padding >= window.innerHeight) {
                    newY = window.innerHeight - size.h - padding;
                }

                this.modal.style.left = newX + 'px';
                this.modal.style.top = newY + 'px';
                this.modal.style.right = 'unset';
                this.modal.style.bottom = 'unset';
                dragging = [e.clientX, e.clientY];
            }
        });

        Dom.addEvent(document.body, 'mouseup', e => {
            dragging = false;
        });

        this.setContent(content);
    }

    setContent(content) {
        this.modalBody.innerHTML = '';
        // 渲染 body 内容
        if (typeof content === 'string') {
            this.modalBody.innerHTML = content;
        } else if (Utils.isFn(content)) {
            content(this.modalBody);
        }
    }

    setMsg(msg) {
        this.messager.innerHTML = msg;
    }

    show(isHide) {
        this.modal.style.display = isHide ? 'none' : 'block';
        if (this.dimmer) {
            this.dimmer.show(isHide);
        }
    }

    hide() {
        this.show(true);
    }


    destroy(explicit) {
        if (explicit || this.userOptions.type === 'confirm' || this.userOptions.type === 'alert') {
            document.body.removeChild(this.modal);
            if (this.dimmer) {
                this.dimmer.destory();
            }
            return false;
        }
        this.show(true);
    }
}

export default Modal;